<?php
namespace app\admin\controller;
use app\CommonController;
use app\service\MenuService;
use app\service\UserService;
use think\exception\ValidateException;
use app\model\Menu;
class Admin extends CommonController
{

    public static $_currentUri = "";
    public $title;
    public function initialize()
    {

        $this->service = $this->app->make(MenuService::class);
        defined("UID") or  define("UID", session("uid"));
        defined("IS_ROOT") or  define("IS_ROOT", is_administrator());
        $uri = $this->request->baseUrl();
        $uri = str_replace(".html","",$uri);
        $uri = ltrim($uri, "/");
        self::$_currentUri = strtolower($uri);
        // 检测系统权限
        if (!IS_ROOT) {
            $access = $this->accessControl();
            if (false === $access) {
                 $this->error('403:禁止访问');
            } elseif (null === $access) {
                //检测访问权限
                if (!$this->checkRule(self::$_currentUri)) {
                    $this->error('未授权访问!');
                }
            }
        }
        $this->assign('menus', $this->getMenus());
    }

    /**
     * 检查角色
     * @return bool
     */
    final protected function checkRule($uri)
    {
        $userService = $this->app->make(UserService::class);
        $user = $userService->get(UID);
        $privileges = [];
        foreach ($user->roles as $role) {
            $privileges = array_merge($privileges, explode(",", $role->privileges));
        }
        $menu = $this->service->getOne(["state" => \app\model\User::USER_STATUS_ACTIVE, "url" =>$uri]);
        if (empty($menu)) {
            return false;
        }
        if (in_array($menu->id, $privileges)) {
            return true;
        }
        return false;
    }

    /**
     * 获取所有菜单
     * @return void
     */
    final public function getMenus()
    {
        $controller = $this->request->controller();
        $menus = session('ADMIN_MENU_LIST.' . $controller);
        if (empty($menus)) {
            $main = $this->service->getAll(["status" =>Menu::MENU_STATUS_ACTIVE, "pid" => 0], "*", "sort asc");
            if (empty($main)) {
                throw new ValidateException("系统错误，暂无菜单");
            }
            $menus['main'] = $main->toArray();
            $menus['child'] = []; //设置子节点
            foreach ($menus['main'] as $key => $item) {
                // 判断主菜单权限
                if (!IS_ROOT && !$this->checkRule($item["url"])) {
                    unset($menus['main'][$key]);
                    continue;//继续循环
                }
                $menus['main'][$key]['class'] = '';
                if (self::$_currentUri == strtolower($item['url'])) {
                    $menus['main'][$key]['class'] = 'layui-this';
                }
            }

            // 查找当前子菜单
            $sub = $this->service->getOne([
                ['url', '=', self::$_currentUri],
                ['pid', '<>', 0],
                ['status', '=',Menu::MENU_STATUS_ACTIVE],
            ]);
            if (!empty($sub) && !empty($sub->pid)) {
                // 查找当前主菜单
                $nav = $this->service->getOne(["id" => $sub->pid]);
                if ($nav->pid) {
                    $nav = $this->service->getOne(["id" => $nav->pid]);
                }
                foreach ($menus['main'] as $key => $item) {
                    // 获取当前主菜单的子菜单项
                    if ($item['id'] == $nav->id) {
                        $menus['main'][$key]['class'] = 'layui-this';
                        //生成child树
                        $where =[["group", "!=", ""], ["pid", "=", $item["id"]]];
                        $groups = $this->service->getGroup($where,"group");
                        //获取二级分类的合法url
                        $where = array();
                        $where['pid'] = $item['id'];
                        $where['is_menu'] = 1;
                        $where["status"] =Menu::MENU_STATUS_ACTIVE;
                        $secondUrls = $this->service->column($where,'url');
                        if (!IS_ROOT) {
                            // 检测菜单权限
                            $toCheckUrls = array();
                            foreach ($secondUrls as $toCheckUrl) {
                                if ($this->checkRule($toCheckUrl)) {
                                    $toCheckUrls[] = $toCheckUrl;
                                }
                            }
                        }

                        // 按照分组生成子菜单树
                        foreach ($groups as $g) {
                            $map = [
                                ["group", "=", $g],
                                ["status", "=",Menu::MENU_STATUS_ACTIVE],
                                ["is_menu", "=", 1],
                                ["pid", "=", $item["id"]],
                            ];
                           if (isset($toCheckUrls)) {
                                if (empty($toCheckUrls)) {
                                    continue;
                                } else {
                                    $map[] = ["url", "in", $toCheckUrls];
                                }
                            }
                            $menuList = $this->service->getAll($map, "id,pid,name,url,icon", "sort asc");
                            if ($menuList->isEmpty()) {
                                continue;
                            }
                            $menus['child'][$g] = list_to_tree($menuList->toArray(), 'id', 'pid', 'operater', $item['id']);
                        }
                    }
                }
            }
            session('ADMIN_MENU_LIST.' . $controller, $menus);
        }
        return $menus;
    }


    final protected function accessControl()
    {
        $check = self::$_currentUri;
        $allow = config('global.ALLOW_VISIT');
        $deny = config('global.DENY_VISIT');
        if (!empty($deny) && in_array_case($check, $deny)) {
            return false;//非超管禁止访问deny中的方法
        }
        if (!empty($allow) && in_array_case($check, $allow)) {
            return true;
        }
        return null;//需要检测节点权限
    }

}
